<template>
  <div :class="['aime-dialog-box', type]">
    <AnalyzeStatus
      v-if="needAnalyzeStatus"
      :status="status"
      :isGenerating="isGenerating"
      :hasRefresh="hasRefresh"
      :steps="steps"
      @refresh="refresh"
      @scrollToBottom="$emit('scrollToBottom')"
    />
    <div
      :class="['container', type]"
      v-if="!['error', 'pending'].includes(status) || (status === 'pending' && content)"
    >
      <img v-if="type === 'recommend'" :src="imgSrouce.recommend" alt="" class="recommend-icon" />
      <div :class="{ content: true, recommend: type === 'recommend' }">
        <Charts
          v-if="chart.config.length && chart.chart_data.length"
          :config="chart.config"
          :chartData="chart.chart_data"
        />
        <span v-if="needTypeWriter" ref="gcContent"></span>
        <span v-else ref="gcContent" v-html="showContent"></span>
      </div>
      <div class="controls" v-if="needControls">
        <div class="imgs">
          <div class="img">
            <img
              :src="likeStatusNow === 'LIKE' ? imgSrouce.thumbActive : imgSrouce.thumb"
              alt=""
              @click.stop="feedback('LIKE')"
            />
          </div>
          <div class="img">
            <img
              :src="likeStatusNow === 'DISLIKE' ? imgSrouce.thumbActive : imgSrouce.thumb"
              alt=""
              class="dislike"
              @click.stop="feedback('DISLIKE')"
            />
          </div>
        </div>
        <div class="copy" @click.stop="copy"><img :src="imgSrouce.copy" alt="" /></div>
      </div>
    </div>
  </div>
</template>

<script>
import AnalyzeStatus from './AnalyzeStatus.vue';
import { copyToClipboard, errorReport } from '../utils/tools';
import Typed from 'typed.js';
import { feedback } from '../apis/aimeApi';
// 不能直接使用markdown-it,因为此包不支持ESM模块命名导出，会导致matrix编译报错。使用预构建
import markdownIt from 'markdown-it/dist/markdown-it.js';
import Charts from './Charts.vue';

export default {
  name: 'AimeDialogBox',
  components: {
    AnalyzeStatus,
    Charts
  },
  props: {
    // 对话框内容
    content: {
      type: String,
      default: '',
      required: true
    },
    // 是否需要打字机效果
    needTypeWriter: {
      type: Boolean,
      default: true,
      required: false
    },
    // 需要底部操作栏
    needControls: {
      type: Boolean,
      default: true,
      required: false
    },
    // 需要分析步骤
    needAnalyzeStatus: {
      type: Boolean,
      default: true,
      required: false
    },
    likeStatus: {
      type: 'LIKE' | 'DISLIKE' | '',
      default: '',
      required: false
    },
    // 打印速度
    typeSpeed: {
      type: Number,
      default: 0,
      required: false
    },
    startDelay: {
      type: Number,
      default: 10,
      required: false
    },
    // 对话框类型
    type: {
      type: 'chat' | 'recommend',
      default: 'chat',
      required: false
    },
    // 当前状态
    status: {
      type: 'pending' | 'success' | 'error',
      default: 'pending',
      required: false
    },
    // 当前消息ID
    msgId: {
      type: String,
      default: '',
      required: false
    },
    // 是否可以重新生成
    hasRefresh: {
      type: Boolean,
      default: false,
      required: false
    },
    // 步骤内容
    steps: {
      type: Array,
      default: () => [],
      required: false
    },
    // 图表内容
    chart: {
      type: Object,
      default: () => ({ config: [], chart_data: [] }),
      required: false
    }
  },
  data() {
    return {
      imgSrouce: {
        thumb:
          '//i.thsi.cn/staticS3/mobileweb-upload-static-server.img/m/atom/2fedd1be-62eb-4b65-8a29-4ac40dca876c.png',
        thumbActive:
          '//i.thsi.cn/staticS3/mobileweb-upload-static-server.img/m/atom/e2b9fb82-ca2a-464e-a3c3-e3dd7954b6c7.png',
        copy: '//i.thsi.cn/staticS3/mobileweb-upload-static-server.img/m/atom/d12d25f6-d08d-45a7-b2a5-ae3392bbcf33.png',
        recommend:
          '//i.thsi.cn/staticS3/mobileweb-upload-static-server.img/m/atom/4647fb58-9fc0-4b99-8df1-c1c1b3e05fd0.png'
      },
      typedIns: null,
      mdIns: null,
      likeStatusNow: ''
    };
  },
  computed: {
    showContent() {
      const content = this.content && this.content.replace(/\n/g, '<br/>');
      return this.mdIns.render(content);
    },
    isGenerating() {
      return !!this.steps.find(item => ['EXPLAIN', 'CHART'].includes(item.type));
    }
  },
  methods: {
    copy() {
      if (!this.$refs.gcContent.innerText) {
        return;
      }
      copyToClipboard(this.$refs.gcContent.innerText);
      this.showToast('已复制');
    },
    // 重新生成
    refresh() {
      this.$emit('refresh', this.msgId);
    },
    // 反馈
    feedback(likeStatus) {
      if (likeStatus !== this.likeStatusNow) {
        const params = { msg_id: this.msgId, feedback: likeStatus, content: '' };
        feedback(params)
          .then(res => {
            if (res.status_code) {
              throw new Error(
                `反馈接口status_code非0，入参为${JSON.stringify(params)}，响应值为${JSON.stringify(
                  res
                )}`
              );
            } else {
              this.likeStatusNow = likeStatus;
              this.showToast(likeStatus === 'LIKE' ? '点赞成功！' : '谢谢反馈！');
            }
          })
          .catch(error => {
            errorReport({
              name: `反馈接口报错。${error.name}`,
              message: error.message,
              stack: error.stack
            });
          });
      } else {
        this.showToast(likeStatus === 'LIKE' ? '点赞成功！' : '谢谢反馈！');
      }
    }
  },
  beforeDestroy() {
    if (this.typedIns) {
      this.typedIns.destroy();
    }
  },
  created() {
    this.mdIns = new markdownIt({ html: true, breaks: true });
  },
  watch: {
    content: {
      handler(val) {
        if (!this.needTypeWriter || !val) {
          return;
        }
        this.$nextTick(() => {
          this.typedIns && this.typedIns.destroy();
          this.typedIns = new Typed(this.$refs.gcContent, {
            strings: [this.showContent],
            // 打印速度
            typeSpeed: this.typeSpeed,
            // 关闭循环
            loop: false,
            // 展示光标
            showCursor: false,
            // 开始之前延迟时间
            startDelay: this.startDelay,
            onBegin: () => {
              this.$emit('typeStart');
            },
            onComplete: () => {
              this.$emit('typeEnd');
            }
          });
        });
      },
      immediate: true
    },
    likeStatus: {
      handler(val) {
        this.likeStatusNow = val;
      },
      immediate: true
    }
  },
  inject: ['showToast']
};
</script>
<style lang="less" scoped>
.aime-dialog-box {
  display: flex;
  justify-content: flex-start;
  width: 400px;
  &.chat {
    flex-direction: column;
    margin-top: 24px;
  }
  &.recommend {
    margin-top: 8px;
    cursor: pointer;
  }
  .container {
    display: flex;
    background: #292933;
    border: 1px solid #292933;
    padding: 12px 16px;
    &.chat {
      justify-content: center;
      flex-direction: column;
      border-radius: 4px 12px 12px 12px;
    }
    &.recommend {
      align-items: center;
      border-radius: 12px;
    }
    .recommend-icon {
      width: 14px;
      height: 14px;
      margin-right: 8px;
    }
    .content {
      font-family: PingFangSC-Regular;
      font-size: 16px;
      color: #e9e9f2;
      line-height: 28px;
      font-weight: 400;
      /deep/code {
        white-space: normal;
      }
      /deep/li {
        list-style-type: none;
      }
      &.recommend:hover {
        color: #3377e8;
      }
    }
    .controls {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 12px;
      .imgs {
        display: flex;
        align-items: center;
        .img {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 24px;
          height: 24px;
          border-radius: 4px;
          cursor: pointer;
          &:last-child {
            margin-left: 8px;
          }
          &:hover {
            background: #111117;
          }
          img {
            width: 16px;
            height: 16px;
          }
          .dislike {
            transform: rotateX(180deg);
          }
        }
      }
      .copy {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 24px;
        height: 24px;
        border-radius: 4px;
        cursor: pointer;
        &:hover {
          background: #111117;
        }
        img {
          width: 16px;
          height: 16px;
        }
      }
    }
  }
}
</style>
